home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / idletime / print.c < prev   
Encoding:
C/C++ Source or Header  |  1990-05-25  |  24.2 KB  |  694 lines

  1. /*
  2.  * print.c --
  3.  *    Routines to print out program execution times, and filesystem stats.
  4.  */
  5.  
  6. #include "sprite.h"
  7. #include "status.h"
  8. #include "stdio.h"
  9. #include "proc.h"
  10. #include "vm.h"
  11. #include "spriteTime.h"
  12. #include "sysStats.h"
  13. #include "kernel/fs.h"
  14. #include "kernel/fsStat.h"
  15. #include "kernel/sched.h"
  16. #include "kernel/vm.h"
  17.  
  18.  
  19. /*
  20.  *----------------------------------------------------------------------
  21.  *
  22.  * PrintTimes --
  23.  *
  24.  *    Print the resource usage (user and kernel CPU time) and elapsed time.
  25.  *
  26.  * Results:
  27.  *    None.
  28.  *
  29.  * Side effects:
  30.  *    Prints to the specified stream
  31.  *
  32.  *----------------------------------------------------------------------
  33.  */
  34. void
  35. PrintTimes(stream, usagePtr, timePtr)
  36.     FILE *stream;
  37.     Proc_ResUsage *usagePtr;
  38.     Time *timePtr;
  39. {
  40.     Time delta;
  41.     if (usagePtr != NULL) {
  42.     Time_Add(usagePtr->userCpuUsage, usagePtr->childUserCpuUsage,
  43.                      &delta);
  44.     fprintf(stream, "%d.%03du ", delta.seconds,
  45.                    delta.microseconds / 1000);
  46.     Time_Add(usagePtr->kernelCpuUsage, usagePtr->childKernelCpuUsage,
  47.                      &delta);
  48.     fprintf(stream, "%d.%03ds ", delta.seconds,
  49.                    delta.microseconds / 1000);
  50.     }
  51.     if (timePtr != NULL) {
  52.     int seconds = timePtr->seconds;
  53.     if (seconds >= 3600) {
  54.         fprintf(stream, "%d:", seconds / 3600);
  55.         seconds = seconds % 3600;
  56.     }
  57.     if (seconds >= 60) {
  58.         fprintf(stream, "%d:", seconds / 60);
  59.         seconds = seconds % 60;
  60.     }
  61.     fprintf(stream, "%d.%03d", seconds,
  62.                    timePtr->microseconds / 1000);
  63.     }
  64.     fprintf(stream, "\n");
  65. }
  66.  
  67.  
  68. /*
  69.  *----------------------------------------------------------------------
  70.  *
  71.  * PrintIdleTime --
  72.  *
  73.  *    Given two samples sched module statistics, this computes
  74.  *    the differenc in idle ticks and, using the time, computes
  75.  *    a utilization.
  76.  *
  77.  * Results:
  78.  *    None.
  79.  *
  80.  * Side effects:
  81.  *    Prints to the specified stream
  82.  *
  83.  *----------------------------------------------------------------------
  84.  */
  85. void
  86. PrintIdleTime(stream, startSchedPtr, endSchedPtr, timePtr)
  87.     FILE *stream;
  88.     Sched_Instrument *startSchedPtr, *endSchedPtr;
  89.     Time *timePtr;
  90. {
  91.     register     highTicks;
  92.     double     lowTicks;
  93.  
  94.     Sched_Instrument zeroStats;
  95.     if (startSchedPtr == NULL) {
  96.     bzero(&zeroStats, sizeof(Sched_Instrument));
  97.     startSchedPtr = &zeroStats;
  98.     }
  99.     highTicks = endSchedPtr->processor[0].idleTicksOverflow -
  100.         startSchedPtr->processor[0].idleTicksOverflow;
  101.     lowTicks = endSchedPtr->processor[0].idleTicksLow -
  102.         startSchedPtr->processor[0].idleTicksLow;
  103.  
  104.     if (highTicks != 0) {
  105.     fprintf(stream, "(High ticks = %d)", highTicks);
  106.     }
  107.     if (timePtr->seconds == 0 && timePtr->microseconds == 0) {
  108.     fprintf(stream, "Idle ticks --/-- = 100%% Idle, Elapsed time ");
  109.     } else {
  110.     lowTicks /= 
  111.       (double)timePtr->seconds + (double) (timePtr->microseconds)/1000000.;
  112.     fprintf(stream, "\nIdle ticks %0.0f/%d = %6.2f%% Idle,\nContext Switches %d, involuntary %d, full %d,\nElapsed time ",
  113.            lowTicks,
  114.            endSchedPtr->processor[0].idleTicksPerSecond,
  115.            (double)lowTicks/(double)endSchedPtr->processor[0].idleTicksPerSecond * 100.,
  116.            endSchedPtr->processor[0].numContextSwitches - startSchedPtr->processor[0].numContextSwitches,
  117.            endSchedPtr->processor[0].numInvoluntarySwitches - startSchedPtr->processor[0].numInvoluntarySwitches,
  118.            endSchedPtr->processor[0].numFullCS - startSchedPtr->processor[0].numFullCS);
  119.     }
  120.     PrintTimes(stream, (Proc_ResUsage *)0, timePtr);
  121. }
  122.  
  123.  
  124. /*
  125.  *----------------------------------------------------------------------
  126.  *
  127.  * PrintFsStats --
  128.  *
  129.  *    Print out the filesystem statistics.  If both a start and end
  130.  *    sample of the statistics are given then the differences between
  131.  *    the two are printed.  To just print the total cumulative statistics
  132.  *    from one sample, specify a single Fs_Stats buffer with the 'end'
  133.  *    parameter.
  134.  *
  135.  * Results:
  136.  *    None.
  137.  *
  138.  * Side effects:
  139.  *    Prints to the specified stream
  140.  *
  141.  *----------------------------------------------------------------------
  142.  */
  143. void
  144. PrintFsStats(stream, start, end, verbose)
  145.     FILE *stream;    /* Output stream */
  146.     Fs_Stats *start;    /* 0, or address of "before run" statistics */
  147.     Fs_Stats *end;    /* End of run statistics */
  148.     int verbose;    /* If true, everything is dumped */
  149. {
  150.     register int t1, t2, t3, t4, t5;
  151.     Fs_Stats zeroStats;
  152.  
  153.     if (start == (Fs_Stats *)0) {
  154.     bzero(&zeroStats, sizeof(Fs_Stats));
  155.     start = &zeroStats;
  156.     }
  157.     /*
  158.      * Print cache size
  159.      */
  160.     fprintf(stream, "Cache blocks max %d min %d number %d/%d free %d/%d limit %d\n",
  161.                end->blockCache.maxCacheBlocks,
  162.                end->blockCache.minCacheBlocks,
  163.                start->blockCache.numCacheBlocks,
  164.                end->blockCache.numCacheBlocks,
  165.                start->blockCache.numFreeBlocks,
  166.                end->blockCache.numFreeBlocks,
  167.                end->blockCache.maxNumBlocks);
  168.  
  169.     /*
  170.      * Print bytes read traffic ratio
  171.      */
  172.     t1 = end->blockCache.bytesRead - start->blockCache.bytesRead;
  173.     t2 = end->blockCache.dirBytesRead - start->blockCache.dirBytesRead;
  174.     t3 = end->gen.remoteBytesRead - start->gen.remoteBytesRead;
  175.     t4 = end->gen.fileBytesRead - start->gen.fileBytesRead;
  176.     t5 = end->gen.physBytesRead - start->gen.physBytesRead;
  177.     fprintf(stream, "Bytes read %d+%d remote %d disk %d+%d",
  178.                t1, t2, t3, t4, t5);
  179.     if (t1 + t2 > 0) {
  180.     fprintf(stream, "\ttraffic ratio %%%d\n",
  181.                (int)((double)(t3+t4+t5)/(double)(t1+t2) * 100.));
  182.     } else {
  183.     fprintf(stream, "\n");
  184.     }
  185.  
  186.     /*
  187.      * Print bytes written traffic ratio
  188.      */
  189.     t1 = end->blockCache.bytesWritten - start->blockCache.bytesWritten +
  190.     (end->blockCache.fileDescWrites - start->blockCache.fileDescWrites +
  191.      end->blockCache.indBlockWrites - start->blockCache.indBlockWrites) *
  192.     FS_BLOCK_SIZE;
  193.     t2 = end->blockCache.dirBytesWritten - start->blockCache.dirBytesWritten;
  194.     t3 = end->gen.remoteBytesWritten - start->gen.remoteBytesWritten;
  195.     t4 = end->gen.fileBytesWritten - start->gen.fileBytesWritten;
  196.     t5 = end->gen.physBytesWritten - start->gen.physBytesWritten;
  197.     fprintf(stream, "Bytes written %d+%d remote %d disk %d+%d",
  198.                t1, t2, t3, t4, t5);
  199.     if (t1 + t2 > 0) {
  200.     fprintf(stream, "\ttraffic ratio %%%d",
  201.                (int)((double)(t3+t4+t5)/(double)(t1+t2) * 100.));
  202.     }
  203.     fprintf(stream, "\n");
  204.  
  205.     if (verbose) {
  206.     /*
  207.      * Print device bytes and zero fills
  208.      */
  209.     t1 = end->gen.deviceBytesWritten - start->gen.deviceBytesWritten;
  210.     t2 = end->gen.deviceBytesRead - start->gen.deviceBytesRead;
  211.     fprintf(stream, "Dev bytes read %d written %d\n", t1, t2);
  212.     t1 = end->blockCache.readZeroFills - start->blockCache.readZeroFills;
  213.     t2 = end->blockCache.writeZeroFills1 -
  214.         start->blockCache.writeZeroFills1;
  215.     t3 = end->blockCache.writeZeroFills2 -
  216.         start->blockCache.writeZeroFills2;
  217.     t4 = end->blockCache.fragZeroFills - start->blockCache.fragZeroFills;
  218.     fprintf(stream, "Zero Fills read %d write1 %d write2 %d frag %d\n",
  219.                    t1, t2, t3, t4);
  220.     t1 = end->blockCache.appendWrites - start->blockCache.appendWrites;
  221.     t2 = end->blockCache.overWrites - start->blockCache.overWrites;
  222.     t3 = end->blockCache.domainReadFails -
  223.         start->blockCache.domainReadFails;
  224.     fprintf(stream, "Appends %d Overwrites %d Failed Reads %d\n",
  225.                    t1, t2, t3);
  226.     }
  227.     t1 = end->blockCache.readAccesses - start->blockCache.readAccesses +
  228.      end->blockCache.fragAccesses - start->blockCache.fragAccesses +
  229.      end->blockCache.fileDescReads - start->blockCache.fileDescReads +
  230.      end->blockCache.indBlockAccesses - start->blockCache.indBlockAccesses +
  231.      end->blockCache.dirBlockAccesses - start->blockCache.dirBlockAccesses;
  232.     t2 = end->blockCache.readHitsOnDirtyBlock -
  233.     start->blockCache.readHitsOnDirtyBlock;
  234.     t3 = end->blockCache.readHitsOnCleanBlock -
  235.     start->blockCache.readHitsOnCleanBlock;
  236.     t4 = end->blockCache.fragHits - start->blockCache.fragHits +
  237.      end->blockCache.fileDescReadHits - start->blockCache.fileDescReadHits +
  238.      end->blockCache.indBlockHits - start->blockCache.indBlockHits +
  239.      end->blockCache.dirBlockHits - start->blockCache.dirBlockHits;
  240.     fprintf(stream, "Cache reads %d hits: dirty %d clean %d other %d",
  241.                t1, t2, t3, t4);
  242.     if (t1 != 0) {
  243.     fprintf(stream, "\thit ratio %%%d",
  244.                (int)((double)(t2+t3+t4)/(double)t1 * 100.));
  245.     }
  246.     fprintf(stream, "\n");
  247.  
  248.     t1 = end->blockCache.readAheads - start->blockCache.readAheads;
  249.     t2 = end->blockCache.readAheadHits - start->blockCache.readAheadHits;
  250.     t3 = end->blockCache.allInCacheCalls - start->blockCache.allInCacheCalls;
  251.     t4 = end->blockCache.allInCacheTrue - start->blockCache.allInCacheTrue;
  252.     if (t1 > 0) {
  253.     fprintf(stream, "Read Ahead: hits %d/%d all-in-cache %d/%d\n",
  254.             t2, t1, t4, t3);
  255.     }
  256.  
  257.     t1 = end->blockCache.writeAccesses - start->blockCache.writeAccesses +
  258.      end->blockCache.fileDescWrites - start->blockCache.fileDescWrites +
  259.      end->blockCache.indBlockWrites - start->blockCache.indBlockWrites +
  260.      end->blockCache.dirBlockWrites - start->blockCache.dirBlockWrites;
  261.     t2 = end->blockCache.partialWriteHits - start->blockCache.partialWriteHits +
  262.     end->blockCache.fileDescWriteHits - start->blockCache.fileDescWriteHits;
  263.     t3 = end->blockCache.partialWriteMisses -
  264.     start->blockCache.partialWriteMisses;
  265.     t4 = end->blockCache.blocksWrittenThru -
  266.     start->blockCache.blocksWrittenThru;
  267.     fprintf(stream, "Cache writes %d hits %d misses %d thru %d",
  268.                t1, t2, t3, t4);
  269.     if (t1 != 0) {
  270.     fprintf(stream, "\ttraffic ratio %%%d",
  271.                (int)((double)(t3+t4)/(double)t1 * 100.));
  272.     }
  273.     fprintf(stream, "\n");
  274.     
  275.     fprintf(stream, "Write thru %d data %d indirect %d desc %d dir %d\n",
  276.                t4,
  277.                end->blockCache.dataBlocksWrittenThru -
  278.                start->blockCache.dataBlocksWrittenThru,
  279.                end->blockCache.indBlocksWrittenThru -
  280.                start->blockCache.indBlocksWrittenThru,
  281.                end->blockCache.descBlocksWrittenThru -
  282.                start->blockCache.descBlocksWrittenThru,
  283.                end->blockCache.dirBlocksWrittenThru -
  284.                start->blockCache.dirBlocksWrittenThru);
  285.     if (end->blockCache.fileDescReads > 0) {
  286.     fprintf(stream, "File descriptor reads %d hits %d writes %d hits %d\n",
  287.                    end->blockCache.fileDescReads -
  288.                    start->blockCache.fileDescReads,
  289.                    end->blockCache.fileDescReadHits -
  290.                    start->blockCache.fileDescReadHits,
  291.                    end->blockCache.fileDescWrites -
  292.                    start->blockCache.fileDescWrites,
  293.                    end->blockCache.fileDescWriteHits -
  294.                    start->blockCache.fileDescWriteHits);
  295.     }
  296.     if (end->blockCache.indBlockAccesses > 0) {
  297.     fprintf(stream, "Indirect block reads %d hits %d writes %d\n",
  298.                end->blockCache.indBlockAccesses -
  299.                start->blockCache.indBlockAccesses,
  300.                end->blockCache.indBlockHits -
  301.                start->blockCache.indBlockHits,
  302.                end->blockCache.indBlockWrites -
  303.                start->blockCache.indBlockWrites);
  304.     }
  305.     if (end->blockCache.dirBlockAccesses > 0) {
  306.     fprintf(stream, "Directory block reads %d hits %d writes %d\n",
  307.                    end->blockCache.dirBlockAccesses -
  308.                    start->blockCache.dirBlockAccesses,
  309.                    end->blockCache.dirBlockHits -
  310.                    start->blockCache.dirBlockHits,
  311.                    end->blockCache.dirBlockWrites -
  312.                    start->blockCache.dirBlockWrites);
  313.     }
  314.     if (end->blockCache.vmRequests > 0) {
  315.     fprintf(stream, "VM requests %d tried %d gave %d\n",
  316.                    end->blockCache.vmRequests -
  317.                    start->blockCache.vmRequests,
  318.                    end->blockCache.triedToGiveToVM -
  319.                    start->blockCache.triedToGiveToVM,
  320.                    end->blockCache.vmGotPage -
  321.                    start->blockCache.vmGotPage);
  322.     }
  323.     fprintf(stream, "Cache blocks created %d, alloc from free %d part %d lru %d\n",
  324.                    end->blockCache.unmapped -
  325.                    start->blockCache.unmapped,
  326.                    end->blockCache.totFree -
  327.                    start->blockCache.totFree,
  328.                    end->blockCache.partFree -
  329.                    start->blockCache.partFree,
  330.                    end->blockCache.lru -
  331.                    start->blockCache.lru);
  332.     if (end->alloc.blocksAllocated > 0) {
  333.     fprintf(stream, "Disk blocks alloc %d free %d search %d/%d hash %d\n",
  334.                    end->alloc.blocksAllocated -
  335.                    start->alloc.blocksAllocated,
  336.                    end->alloc.blocksFreed -
  337.                    start->alloc.blocksFreed,
  338.                    end->alloc.cylsSearched -
  339.                    start->alloc.cylsSearched,
  340.                    end->alloc.cylBitmapSearches -
  341.                    start->alloc.cylBitmapSearches,
  342.                    end->alloc.cylHashes -
  343.                    start->alloc.cylHashes);
  344.     fprintf(stream, "Fragments alloc %d free %d upgrade %d blocks made %d used %d, bad hints %d\n",
  345.                    end->alloc.fragsAllocated -
  346.                    start->alloc.fragsAllocated,
  347.                    end->alloc.fragsFreed -
  348.                    start->alloc.fragsFreed,
  349.                    end->alloc.fragUpgrades -
  350.                    start->alloc.fragUpgrades,
  351.                    end->alloc.fragToBlock -
  352.                    start->alloc.fragToBlock,
  353.                    end->alloc.fullBlockFrags -
  354.                    start->alloc.fullBlockFrags,
  355.                    end->alloc.badFragList -
  356.                    start->alloc.badFragList);
  357.     }
  358.     if (end->nameCache.accesses > 0) {
  359.     fprintf(stream, "Name cache entries %d accesses %d hits %d replaced %d\n",
  360.                end->nameCache.size,
  361.                end->nameCache.accesses -
  362.                start->nameCache.accesses,
  363.                end->nameCache.hits -
  364.                start->nameCache.hits,
  365.                end->nameCache.replacements -
  366.                start->nameCache.replacements);
  367.     }
  368.     fprintf(stream, "Handles %d created %d installed %d hits %d old %d version %d flush %d\n",
  369.                end->handle.exists,
  370.                end->handle.created -
  371.                start->handle.created,
  372.                end->handle.installCalls -
  373.                start->handle.installCalls,
  374.                end->handle.installHits -
  375.                start->handle.installHits,
  376.                0,
  377.                end->handle.versionMismatch -
  378.                start->handle.versionMismatch,
  379.                end->handle.cacheFlushes -
  380.                start->handle.cacheFlushes);
  381.     fprintf(stream, "\tfetched %d hits %d released %d locks %d/%d wait %d\n",
  382.                end->handle.fetchCalls -
  383.                start->handle.fetchCalls,
  384.                end->handle.fetchHits -
  385.                start->handle.fetchHits,
  386.                end->handle.release -
  387.                start->handle.release,
  388.                end->handle.locks -
  389.                start->handle.locks,
  390.                end->handle.locks -
  391.                start->handle.locks,
  392.                end->handle.lockWaits -
  393.                start->handle.lockWaits);
  394.     fprintf(stream, "Segments fetched %d hits %d\n",
  395.                end->handle.segmentFetches -
  396.                start->handle.segmentFetches,
  397.                end->handle.segmentHits -
  398.                start->handle.segmentHits);
  399.     fprintf(stream, "Lookup relative %d absolute %d redirect %d found %d loops %d timeouts %d stale %d\n",
  400.                end->prefix.relative -
  401.                start->prefix.relative,
  402.                end->prefix.absolute -
  403.                start->prefix.absolute,
  404.                end->prefix.redirects -
  405.                start->prefix.redirects,
  406.                end->prefix.found -
  407.                start->prefix.found,
  408.                end->prefix.loops -
  409.                start->prefix.loops,
  410.                end->prefix.timeouts -
  411.                start->prefix.timeouts,
  412.                end->prefix.stale -
  413.                start->prefix.stale);
  414. }
  415.  
  416.  
  417. /*
  418.  *----------------------------------------------------------------------
  419.  *
  420.  * PrintDiskStats --
  421.  *
  422.  *    Print out statistics for the disks.  If both a start and end
  423.  *    sample of the statistics are given then the differences between
  424.  *    the two are printed.  To just print the total cumulative statistics
  425.  *    from one sample, specify a single VmStats buffer with the 'end'
  426.  *    parameter.
  427.  *
  428.  * Results:
  429.  *    None.
  430.  *
  431.  * Side effects:
  432.  *    Prints to the specified stream
  433.  *
  434.  *----------------------------------------------------------------------
  435.  */
  436. void
  437. PrintDiskStats(stream, start, end)
  438.     FILE         *stream;/* Output stream */
  439.     Sys_DiskStats    *start;    /* 0, or address of "before run" statistics */
  440.     Sys_DiskStats    *end;    /* End of run statistics */
  441. {
  442.     int    i = 0;
  443.     while (1) {
  444.     if (end[i].name[0] == 0) {
  445.         return;
  446.     }
  447.     if (start == 0) {
  448.         fprintf(stream, "Disk (%s, %d): %0.2f%% Idle Reads %d Writes %d\n",
  449.             end[i].name, end[i].controllerID,
  450.             100 * ((float)end[i].idleCount / (float)end[i].numSamples),
  451.             end[i].diskReads, end[i].diskWrites);
  452.     } else {
  453.         fprintf(stream, "Disk (%s, %d) %0.0f%% Idle Reads %d Writes %d\n",
  454.             end[i].name, end[i].controllerID,
  455.             100 * ((float)(end[i].idleCount - start[i].idleCount) /
  456.                    (float)(end[i].numSamples - start[i].numSamples)),
  457.             end[i].diskReads - start[i].diskReads,
  458.             end[i].diskWrites - start[i].diskWrites);
  459.     }
  460.     i++;
  461.     }
  462. }
  463.  
  464.  
  465. /*
  466.  *----------------------------------------------------------------------
  467.  *
  468.  * PrintVmStats --
  469.  *
  470.  *    Print out VM statistics.  If both a start and end
  471.  *    sample of the statistics are given then the differences between
  472.  *    the two are printed.  To just print the total cumulative statistics
  473.  *    from one sample, specify a single VmStats buffer with the 'end'
  474.  *    parameter.
  475.  *
  476.  * Results:
  477.  *    None.
  478.  *
  479.  * Side effects:
  480.  *    Prints to the specified stream
  481.  *
  482.  *----------------------------------------------------------------------
  483.  */
  484. void
  485. PrintVmStats(stream, start, end)
  486.     FILE *stream;    /* Output stream */
  487.     Vm_Stat *start;    /* 0, or address of "before run" statistics */
  488.     Vm_Stat *end;    /* End of run statistics */
  489. {
  490.     register    int    *diffPtr;
  491.     register    int    *startPtr;
  492.     register    int    *endPtr;
  493.     int            i;
  494.     int            inusePages;
  495.     int            totPages;
  496.     int            numModifiedPages;
  497.     Vm_Stat        diffStat;
  498.     int            totPercent;
  499.     int            totFaults;
  500.     int            heapPercent;
  501.     int            stkPercent;
  502.     int            quickPercent;    
  503.     int            totHits;
  504.     int            totPrefetches;
  505.     int            hitPct;
  506.  
  507.     startPtr = (int *)start;
  508.     endPtr = (int *)end;
  509.     diffPtr = (int *)&diffStat;
  510.  
  511.     for (i = 0; 
  512.          i < sizeof(Vm_Stat) / sizeof(int); 
  513.      i++, startPtr++, endPtr++, diffPtr++) {
  514.     *diffPtr = *endPtr - *startPtr;
  515.     }
  516.  
  517.     (void)Vm_Cmd(VM_COUNT_DIRTY_PAGES, &numModifiedPages);
  518.     fprintf(stream, "Kernel VM Pages: %d (Code+Data=%d Stacks=%d)\n",
  519.          end->kernMemPages + end->kernStackPages,
  520.          end->kernMemPages, end->kernStackPages);
  521.     inusePages = end->numDirtyPages + end->numUserPages;
  522.     totPages = end->numFreePages + inusePages;
  523.     fprintf(stream, "User VM Pages:   %d (Free=%d Dirty=%d Res=%d Alloc-list=%d)\n",
  524.         end->numFreePages + end->numDirtyPages + 
  525.         end->numReservePages + end->numUserPages, 
  526.         end->numFreePages, end->numDirtyPages,
  527.         end->numReservePages,
  528.         end->numUserPages);
  529.     fprintf(stream, "Modified pages: Total=%d %%Tot-dirty=%0.2f %%Inuse-dirty=%0.2f\n",
  530.         numModifiedPages,
  531.         (float) (numModifiedPages) / (float)totPages * 100.0,
  532.         (float) (numModifiedPages) / (float)inusePages * 100.0);
  533.     fprintf(stream, "FS Pages: Current=%d Max=%d Min=%d\n", 
  534.         end->fsMap - end->fsUnmap, end->maxFSPages, end->minFSPages);
  535.     fprintf(stream,
  536.          "Faults: %8d (Zero=%d FS=%d Swap=%d Quick=%d Coll=%d)\n", 
  537.          diffStat.totalFaults, diffStat.zeroFilled, diffStat.fsFilled,
  538.          diffStat.psFilled,diffStat.quickFaults, diffStat.collFaults);
  539.     fprintf(stream, "        %8d (Code=%d Heap=%d Stack=%d)\n", 
  540.          diffStat.totalFaults, diffStat.codeFaults, diffStat.heapFaults,
  541.          diffStat.stackFaults);
  542.     fprintf(stream, 
  543.         "Mod page stats:  Pot-mod=%d Not-mod=%d Not-hard-mod=%d\n",
  544.         diffStat.potModPages, diffStat.notModPages, 
  545.         diffStat.notHardModPages);
  546.  
  547.     /*
  548.      * Copy on write. 
  549.      */
  550.     totPages = diffStat.numCOWStkPages + diffStat.numCOWHeapPages;
  551.     totFaults = diffStat.numCOWStkFaults + diffStat.numCOWHeapFaults;
  552.     if (diffStat.numCOWHeapPages > 0) {
  553.     heapPercent = 100.0 * ((float)diffStat.numCOWHeapFaults / 
  554.                       diffStat.numCOWHeapPages);
  555.     } else {
  556.     heapPercent = 0;
  557.     }
  558.     if (diffStat.numCOWStkPages > 0) {
  559.     stkPercent = 100.0 * ((float)diffStat.numCOWStkFaults / 
  560.                       diffStat.numCOWStkPages);
  561.     } else {
  562.     stkPercent = 0;
  563.     }
  564.     if (totPages > 0) {
  565.     totPercent = 100.0 * ((float)totFaults / totPages);
  566.     } else {
  567.     totPercent = 0;
  568.     }
  569.     if (totFaults > 0) {
  570.     quickPercent = 100.0 * ((float)diffStat.quickCOWFaults / totFaults);
  571.     } else {
  572.     quickPercent = 0;
  573.     }
  574.     fprintf(stream, 
  575.         "COW: Heap (%d/%d)=%d%% Stk (%d/%d)=%d%% Tot (%d/%d)=%d%%\n",
  576.         diffStat.numCOWHeapFaults, diffStat.numCOWHeapPages, heapPercent,
  577.         diffStat.numCOWStkFaults, diffStat.numCOWStkPages, stkPercent,
  578.         totFaults, totPages, totPercent);
  579.     fprintf(stream, "     Quick (%d/%d)=%d%%\n",
  580.         diffStat.quickCOWFaults, totFaults, quickPercent);
  581.     /*
  582.      * Copy on reference.
  583.      */
  584.     totPages = diffStat.numCORStkPages + diffStat.numCORHeapPages;
  585.     totFaults = diffStat.numCORStkFaults + diffStat.numCORHeapFaults;
  586.     if (diffStat.numCORHeapPages > 0) {
  587.     heapPercent = 100.0 * ((float)diffStat.numCORHeapFaults / 
  588.                       diffStat.numCORHeapPages);
  589.     } else {
  590.     heapPercent = 0;
  591.     }
  592.     if (diffStat.numCORStkPages > 0) {
  593.     stkPercent = 100.0 * ((float)diffStat.numCORStkFaults / 
  594.                       diffStat.numCORStkPages);
  595.     } else {
  596.     stkPercent = 0;
  597.     }
  598.     if (totPages > 0) {
  599.     totPercent = 100.0 * ((float)totFaults / totPages);
  600.     } else {
  601.     totPercent = 0;
  602.     }
  603.     fprintf(stream,
  604.             "COR: Heap (%d/%d)=%d%% Stk (%d/%d)=%d%% Tot (%d/%d)=%d%%\n",
  605.         diffStat.numCORHeapFaults, diffStat.numCORHeapPages, heapPercent,
  606.         diffStat.numCORStkFaults, diffStat.numCORStkPages, stkPercent,
  607.         totFaults, totPages, totPercent);
  608.     totPages = diffStat.numCORStkFaults + diffStat.numCORHeapFaults;
  609.     totFaults = diffStat.numCORCOWStkFaults + diffStat.numCORCOWHeapFaults;
  610.     if (diffStat.numCORCOWHeapFaults > 0) {
  611.     heapPercent = 100.0 * ((float)diffStat.numCORCOWHeapFaults / 
  612.                       diffStat.numCORHeapFaults);
  613.     } else {
  614.     heapPercent = 0;
  615.     }
  616.     if (diffStat.numCORCOWStkFaults > 0) {
  617.     stkPercent = 100.0 * ((float)diffStat.numCORCOWStkFaults / 
  618.                       diffStat.numCORStkFaults);
  619.     } else {
  620.     stkPercent = 0;
  621.     }
  622.     if (totPages > 0) {
  623.     totPercent = 100.0 * ((float)totFaults / totPages);
  624.     } else {
  625.     totPercent = 0;
  626.     }
  627.     fprintf(stream,
  628.             "COR-mod: Heap(%d/%d)=%d%% Stk (%d/%d)=%d%% Tot (%d/%d)=%d%%\n",
  629.         diffStat.numCORCOWHeapFaults, diffStat.numCORHeapFaults,heapPercent,
  630.         diffStat.numCORCOWStkFaults, diffStat.numCORStkFaults, stkPercent,
  631.         diffStat.numCORCOWHeapFaults + diffStat.numCORCOWStkFaults,
  632.         diffStat.numCORHeapFaults + diffStat.numCORStkFaults, totPercent);
  633.  
  634.     fprintf(stream, "Swap pages copied: %d\n", diffStat.swapPagesCopied);
  635.     fprintf(stream,
  636.              "Vm allocs: %d (Free=%d From-FS=%d From-alloc-list=%d)\n",
  637.          diffStat.numAllocs, diffStat.gotFreePage, diffStat.gotPageFromFS, 
  638.          diffStat.pageAllocs);
  639.     fprintf(stream, 
  640.          "VM-FS stats: Asked=%d Free-pages=%d Allocs=%d Frees=%d\n",
  641.          diffStat.fsAsked, diffStat.haveFreePage, diffStat.fsMap, 
  642.          diffStat.fsUnmap);
  643.     fprintf(stream, "Alloc-list searches: %d (Free=%d In-use=%d)\n",
  644.          diffStat.numListSearches, diffStat.usedFreePage, 
  645.          diffStat.numListSearches - diffStat.usedFreePage);
  646.     fprintf(stream, "Extra-searches: %d (Lock=%d Ref=%d Dirty=%d)\n",
  647.          diffStat.lockSearched + diffStat.refSearched + 
  648.          diffStat.dirtySearched,
  649.          diffStat.lockSearched, diffStat.refSearched, 
  650.          diffStat.dirtySearched);
  651.     fprintf(stream, "Pages written %d\n", diffStat.pagesWritten);
  652.  
  653.     totPrefetches = diffStat.codePrefetches + diffStat.heapFSPrefetches +
  654.             diffStat.heapSwapPrefetches + diffStat.stackPrefetches;
  655.     if (totPrefetches > 0) {
  656.     totHits = diffStat.codePrefetchHits + diffStat.heapFSPrefetchHits +
  657.           diffStat.heapSwapPrefetchHits + diffStat.stackPrefetchHits;
  658.     fprintf(stream, "Prefetch stats:\n");
  659.     if (diffStat.codePrefetches > 0) {
  660.         hitPct = 100 * ((float)diffStat.codePrefetchHits / 
  661.                 (float)diffStat.codePrefetches);
  662.         fprintf(stream, "    code (%d/%d)=%d%%\n",
  663.             diffStat.codePrefetchHits, diffStat.codePrefetches, hitPct);
  664.     }
  665.     if (diffStat.heapFSPrefetches > 0) {
  666.         hitPct = 100 * ((float)diffStat.heapFSPrefetchHits / 
  667.                 (float)diffStat.heapFSPrefetches);
  668.         fprintf(stream, "    heap-fs (%d/%d)=%d%%\n",
  669.         diffStat.heapFSPrefetchHits, diffStat.heapFSPrefetches, hitPct);
  670.     }
  671.     if (diffStat.heapSwapPrefetches > 0) {
  672.         hitPct = 100 * ((float)diffStat.heapSwapPrefetchHits / 
  673.                 (float)diffStat.heapSwapPrefetches);
  674.         fprintf(stream, "    heap-swp (%d/%d)=%d%%\n",
  675.         diffStat.heapSwapPrefetchHits, diffStat.heapSwapPrefetches, 
  676.         hitPct);
  677.     }
  678.     if (diffStat.stackPrefetches > 0) {
  679.         hitPct = 100 * ((float)diffStat.stackPrefetchHits / 
  680.                 (float)diffStat.stackPrefetches);
  681.         fprintf(stream, "    stack (%d/%d)=%d%%\n",
  682.         diffStat.stackPrefetchHits, diffStat.stackPrefetches, hitPct);
  683.     }
  684.     hitPct = 100 * ((float)totHits / (float)totPrefetches);
  685.     fprintf(stream, "    total (%d/%d)=%d%%\n",
  686.         totHits, totPrefetches, hitPct);
  687.     fprintf(stream, "    aborts=   %d\n", diffStat.prefetchAborts);
  688.     }
  689. #ifdef sun
  690.     fprintf(stream, "Contexts stolen %d pmegs stolen %d\n",
  691.          diffStat.machDepStat.stealContext, diffStat.machDepStat.stealPmeg);
  692. #endif
  693. }
  694.